package org.crud4j.ejb3;

import java.util.Map;

import javax.annotation.Resource;
import javax.ejb.Local;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.crud4j.core.BeforeCreateException;
import org.crud4j.core.BeforeRemoveException;
import org.crud4j.core.BeforeUpdateException;
import org.crud4j.core.CrudBean;
import org.crud4j.core.CrudBrowsePage;
import org.crud4j.core.CrudService;
import org.crud4j.core.IdInUseException;
import org.crud4j.core.RemoveMarkException;

/**
 * Crud service backed by jpa
 */
@Stateless(name = "crud4j/service")
@Local(CrudService.class)
public class Ejb3CrudService extends AbstractJPACrudService {

	@Resource
	private SessionContext sessionContext;

	/**
	 * {@inheritDoc}
	 */
	public CrudBean persist(CrudBean crudBean) throws RemoveMarkException,
			IdInUseException, BeforeCreateException, BeforeUpdateException {
		EntityManagerFactory emf = this.getEntityManagerFactory(crudBean
				.getDef().getType());
		EntityManager em = null;
		try {
			em = emf.createEntityManager();
			String user = sessionContext.getCallerPrincipal().getName();
			crudBean = super.persist(em, user, crudBean);
		} finally {
			if (em != null) {
				em.close();
			}
		}
		return crudBean;
	}

	/**
	 * {@inheritDoc}
	 */
	public void remove(CrudBean crudBean) throws BeforeRemoveException {
		EntityManagerFactory emf = this.getEntityManagerFactory(crudBean
				.getDef().getType());
		EntityManager em = null;
		try {
			em = emf.createEntityManager();
			String user = sessionContext.getCallerPrincipal().getName();
			super.remove(em, user, crudBean);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public CrudBean find(Class type, Map<String, String> ids) {
		EntityManagerFactory emf = this.getEntityManagerFactory(type);
		EntityManager em = null;
		try {
			em = emf.createEntityManager();
			return super.find(em, type, ids);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public CrudBrowsePage filteredBrowse(Class type, Integer pageSize,
			Integer page, Map<String, String> filters) {
		EntityManagerFactory emf = this.getEntityManagerFactory(type);
		EntityManager em = null;
		try {
			em = emf.createEntityManager();
			return super.filteredBrowse(em, type, pageSize, page, filters);
		} finally {
			if (em != null) {
				em.close();
			}
		}
	}
}
